﻿using System;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Security.Cryptography;
using System.Text;

namespace Kay.Communication.Framework.Common
{
    /// <summary>
    /// 公用帮助器
    /// </summary>
    public class Helpers
    {
        /// <summary>
        /// Json 序列化
        /// </summary>
        /// <typeparam name="T">序列化类型</typeparam>
        /// <param name="value">序列化对象</param>
        /// <param name="encod">Json 编码</param>
        /// <returns>序列化后的 Json 内容</returns>
        public static string JsonSerialize<T>(T value, Encoding encod)
        {
            if (value == null)
                return string.Empty;
            string jsonStr;
            var dataContractJsonSerializer = new DataContractJsonSerializer(typeof(T));
            using (var memoryStream = new MemoryStream())
            {
                dataContractJsonSerializer.WriteObject(memoryStream, value);
                jsonStr = encod.GetString(memoryStream.ToArray());
            }
            return jsonStr;
        }

        /// <summary>
        /// 如果字符串是标准 Json 结构，可以使用此方法反序列化成对应的类
        /// </summary>
        /// <param name="value">Json 内容</param>
        /// <param name="encod">Json 编码</param>
        /// <typeparam name="T">反序列化类型</typeparam>
        /// <returns>反序列化成功的类</returns>
        public static T JsonDeserialize<T>(string value, Encoding encod)
        {
            if (string.IsNullOrEmpty(value) || value.Trim() == string.Empty)
                return default(T);
            var dataContractJsonSerializer = new DataContractJsonSerializer(typeof(T));
            T t;
            using (var memoryStream = new MemoryStream(encod.GetBytes(value)))
            {
                var obj = dataContractJsonSerializer.ReadObject(memoryStream);
                t = (T)obj;
            }
            return t;
        }

        /// <summary>
        /// 获取文件的哈希码
        /// </summary>
        /// <param name="fileName">文件名称</param>
        /// <returns>文件的哈希码文本标识形式</returns>
        /// <exception cref="ArgumentNullException">如果文件名称为 NULL，引发此异常</exception>
        /// <exception cref="ArgumentException">如果文件不存在，引发此异常</exception>
        public static string GetFileHashCode(string fileName)
        {
            if (fileName == null) throw new ArgumentNullException("fileName");
            if (!File.Exists(fileName)) throw new ArgumentException("fileName");

            using (var hash = HashAlgorithm.Create())
            {
                using (var stream = File.OpenRead(fileName))
                {
                    var bytesHash = hash.ComputeHash(stream);
                    var textHash = BitConverter.ToString(bytesHash);
                    return textHash;
                }
            }
        }

        /// <summary>
        /// 获取文本的哈希码
        /// </summary>
        /// <param name="value">文本只</param>
        /// <param name="encod">使用的编码</param>
        /// <returns>文本的哈希码文本标识形式</returns>
        /// <exception cref="ArgumentNullException">如果文本为 NULL，引发此异常</exception>
        /// <exception cref="ArgumentException">如果文本为空，引发此异常</exception>
        public static string GetTextHashCode(string value, Encoding encod)
        {
            if (value == null) throw new ArgumentNullException("value");
            if (value.Trim() == string.Empty) throw new ArgumentException("value");

            using (var hash = SHA1.Create())
            {
                var bytes = encod.GetBytes(value);
                var bytesHash = hash.ComputeHash(bytes);
                var textHash = Convert.ToBase64String(bytesHash);
                return textHash;
            }
        }

        /// <summary>
        /// 获取 Guid 的文本标识形式
        /// <para>使用 N 格式化 Guid</para>>
        /// </summary>
        /// <returns>格式化后的 Guid 文本</returns>
        public static string GetGuidToN()
        {
            return Guid.NewGuid().ToString("N").ToUpper();
        }
    }
}